library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity sap1 is
   port(
   	resultado : out std_logic_vector(7 downto 0):="00000000" -- saida do programa
   );
end sap1;

architecture arquitetura of sap1 is
	signal barramento, tmp_ram, A, B, tmp_somador, tmp_acumulador : std_logic_vector(7 downto 0):="00000000";
	signal endereco, tmp_pc, tmp_ri, instrucao : std_logic_vector(3 downto 0):="0000";
	signal cp, ep, ea, su, eu, clr_not, clk: std_logic := '0';
	signal ce_not, lm_not, li_not, ei_not, la_not, lb_not, l0_not, clk_not, clr: std_logic := '1';

	component acumulador
	   port(
   	   La_neg, Ea, CLK: in std_logic;
   	   entrada_bw     : in std_logic_vector(7 downto 0);
   		saida_bw       : out std_logic_vector(7 downto 0);
   	   saida_A        : out std_logic_vector(7 downto 0)
		);
	end component;
	
	component contador_programa
   	port (
   	 	Cp, Ep, CLK_neg, CLR_neg : in std_logic;
   		saida                    : out std_logic_vector(3 downto 0)
   	);   
	end component;
	
	component controlador
	   port(
	   	cp, ep, ea, su, eu, ce_not, lm_not, li_not, ei_not, la_not, lb_not, l0_not: out std_logic;
	      instruction: in std_logic_vector (3 downto 0);
	      clk_out, clk_not_out, clr_out, clr_not_out : out std_logic
	   );
	end component;
	
	component memoria
		port(
			CE_neg     : in std_logic;
			entrada_REM: in std_logic_vector (3 downto 0);
	   	saida_bw   : out std_logic_vector(7 downto 0)
		);
	end component;
	
	component registrador_b
		port(
   	   Lb_neg, CLK : in std_logic;
   	   entrada_bw  : in std_logic_vector(7 downto 0);
		   saida_B     : out std_logic_vector(7 downto 0)
		);
	end component;

	component registrador_instrucao
		port(
			Li_neg, Ei_neg, CLK, CLR : in std_logic;
			entrada_bw               : in std_logic_vector(7 downto 0);
   	   saida_bw                 : out std_logic_vector(3 downto 0);
   	   saida_cs                 : out std_logic_vector(3 downto 0)
		);
	end component;
	
	component registrador_saida
		port(
			Lo_neg, CLK : in std_logic;
   	   entrada_bw  : in std_logic_vector(7 downto 0);
    	 	saida       : out std_logic_vector(7 downto 0)
   	);
	end component;
	
	component remem
		port(
	    	Lm_neg, CLK : in std_logic;
	      entrada_bw  : in std_logic_vector(3 downto 0);
		   saida_RAM   : out std_logic_vector(3 downto 0)
		);
	end component;
	
	component somador_subtrator
		port(
		 	Su, Eu : in std_logic;
			A, B : in std_logic_vector(7 downto 0);
			S : out std_logic_vector(7 downto 0):="00000000"
		);
	end component;
	
begin

	PC: contador_programa port map (cp,ep,clk_not,clr_not,tmp_pc);
	entrada_REM: remem port map (lm_not,clk,barramento(7 downto 4),endereco);
	RAM: memoria port map(ce_not, endereco, tmp_ram);
	RI: registrador_instrucao port map (li_not, ei_not, clk, clr, barramento, tmp_ri, instrucao);
	controlador_sequencializador: controlador port map (cp, ep, ea, su, eu, ce_not, lm_not, li_not, ei_not, la_not, lb_not, l0_not,
	      															 instrucao, clk, clk_not, clr, clr_not);
	acumulador_A: acumulador port map (la_not, ea, clk, barramento, tmp_acumulador, A);
	regB: registrador_b port map (lb_not, clk, barramento, B);
	SS: somador_subtrator port map (su, eu, A, B, tmp_somador);
	regSaida: registrador_saida port map (l0_not, clk, barramento, resultado);
	
	process(ep,ce_not,ei_not,ea,eu)
	begin
		if(ep='1') then
			barramento(7 downto 4)<=tmp_pc;
		elsif(ce_not='0') then
			barramento<=tmp_ram;
		elsif(ei_not='0') then
			barramento(7 downto 4)<=tmp_ri;
		elsif(ea='1') then
			barramento<=tmp_acumulador;
		elsif(eu='1') then
			barramento<=tmp_somador;
		end if;
	end process;

end arquitetura;
